#include <iostream>
#include <string.h>
//#include "LockFile.h"
#include <sstream>
#include "SIGINT_Handler.h"
#include "SignalHandler.h"
#include <stdlib.h>
#include <sys/wait.h>

#include "Writer.h"
#include "Reader.h"
#include "Pipe.h"
#include "Logger.h"

#define	FILENAME	"history"
#define DEBUG_FILENAME "debug"
#define BUFFSIZE 1

using namespace std;

void showHelp();

int main(int argc, char **argv) {
	Logger* logger = new Logger((char *) DEBUG_FILENAME);
	Writer* historyWriter = new Writer((char *) FILENAME);
	Reader* historyReader = new Reader((char *) FILENAME);

	Pipe pipe;

	int parameter;

	string clientName = "";
	string str;

	std::string parentPID;
	std::stringstream out;
	out << getpid();
	parentPID = out.str();

	while ((parameter = getopt (argc, argv, "hd")) != -1){
		switch (parameter){
			case 'd':
				logger->setDebugMode(true);
				break;
			case 'h':
				showHelp();
				exit(0);
				break;
			case '?':
				showHelp();
				exit(0);
				break;
			default:
				cout << "ConcuChat: Opción inválida -" << parameter <<  endl;
				cout << "Use concuchat -h para más información." <<  endl;
				exit(0);
		   }
	}

	cout << "Ingresa tu nombre: ";
	getline(cin, clientName);
	cout << "Gracias " << clientName << ", has entrado a la sala de chat.\n";

	pid_t pid = fork();
	if (pid == 0) {
		logger->log("Escritor: Mensaje bienvenida a los demas clientes.");
		historyWriter->write(parentPID, clientName, historyWriter->getWelcomeMessage());
		logger->log("Escritor: Comienzo a tomar datos de la entrada.");
		while (str != "exit") {
			getline(cin, str);

			if (str.size() > 0) {
				historyWriter->write(parentPID, clientName, str);
			}

			if(str == "exit"){
				logger->log("Escritor: Se recibio \"exit\", termino.");
				char *data = (char *) "1";
				pipe.writeToPipe ( data,strlen(data) );
			}
		}

		logger->log("Escritor: Me destruyo.");
		delete historyWriter;
		exit(0);

	} else {
		pid_t pid2 = fork();

		if (pid2 == 0) {
			string message = "";

			SIGINT_Handler sigint_handler;
			SignalHandler::getInstance()->registrarHandler(SIGINT,
					&sigint_handler);

			int bytes = -1;
			bool hasRead = false;

			char buffer[BUFFSIZE];
			buffer [ bytes ] = '\0';
			logger->log("Lector: Comienzo a leer datos desde el archivo.");
			while (sigint_handler.getGracefulQuit() == 0 && hasRead == false) {
				//sleep(1);
				message = historyReader->read();
				char * pch;
				if (message.size() > 0) {
					logger->log("Lector: Se leyo un nuevo mensaje.");
					pch = strtok((char*) message.c_str(), "\n");
					while (pch != NULL) {
						string line = pch;
						int position = line.find_first_of("|", 0);
						string senderPID = line.substr(0, position);
						if (senderPID != parentPID) {
							line = line.substr(position + 1, line.size());
							cout << line << endl;
						}

						pch = strtok(NULL, "\n");
					}
				}
				bytes = pipe.readFromPipe (buffer,BUFFSIZE);

				if (bytes != -1) {
					hasRead = true;
				}
			}

			logger->log("Lector: Finalizo cerrando el pipe y notificando a los demas clientes.");
			pipe.closePipe();
			historyWriter->write(parentPID, clientName, historyWriter->getGoodbyeMessage());

			SignalHandler::dispose();
			delete historyReader;
			exit(0);

		} else {
			logger->log("Padre: Esperando que mis hijos terminen.");
			wait(NULL);
			wait(NULL);
			logger->log("Padre: Mis hijos terminaron. Cierro mi proceso.");
			cout << "Has salido del chat" << endl;
			exit(0);
		}
	}
}

void showHelp(){
	cout << "..:::ConcuChat:::.." << endl;
	cout << "Aplicación concurrente para conversar." << endl;
	cout << "Desarrollado por: " << endl;
	cout <<	"Acosta Claudia Roxana" << endl;
	cout << "Korzeniewski Claudia" << endl;
	cout << "Cufone Pablo Alfonso" << endl;
	cout << endl;
	cout << "Modo de uso: ./concuChat [OPCION]" << endl;
	cout << "-d \t Activa el modo debug." << endl;
	cout << "-h \t Muestra esta ayuda." << endl;
}
